home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
dev
/
lang
/
sbp3_1e.lzh
/
CANNIBAL.PL
< prev
next >
Wrap
Text File
|
1991-10-31
|
2KB
|
107 lines
/* From the book PROLOG PROGRAMMING IN DEPTH
by Michael A. Covington, Donald Nute, and Andre Vellino.
Copyright 1988 Scott, Foresman & Co.
Non-commercial distribution of this file is permitted. */
/* Modified for Quintus Prolog by Andreas Siebert */
/* CANNIBAL.PL */
/*
* Main predicate
*/
missionaries_and_cannibals :-
ferry([[3,3,l,0,0]],Solution),
fast_reverse(Solution,ReversedSolution),
show_ferry(ReversedSolution).
/*
* How to move people across the river
*/
ferry([OldSit|Rest],Solution) :-
safe_trip(OldSit,NewSit),
\+ member(NewSit,Rest),
check_ferry([NewSit,OldSit|Rest],Solution).
safe_trip([ML,CL,l,MR,CR],[MLL,CLL,r,MRR,CRR]) :-
in_boat(M,C,ML,CL),
MLL is ML - M,
CLL is CL - C,
not_overpowered(MLL,CLL),
MRR is MR + M,
CRR is CR + C,
not_overpowered(MRR,CRR).
safe_trip([ML,CL,r,MR,CR],[MLL,CLL,l,MRR,CRR]) :-
in_boat(M,C,MR,CR),
MLL is ML + M,
CLL is CL + C,
not_overpowered(MLL,CLL),
MRR is MR - M,
CRR is CR - C,
not_overpowered(MRR,CRR).
/*
* How to find out whether we've finished
*/
check_ferry([[0,0,r,3,3]|Rest],[[0,0,r,3,3]|Rest]).
check_ferry(SequenceOfSituations,Solution) :-
ferry(SequenceOfSituations,Solution).
/*
* Other constraints on putting people in the boat
*/
in_boat(M,C,MM,CC) :- boat_load(M,C), M =< MM, C =< CC.
boat_load(1,0).
boat_load(0,1).
boat_load(1,1).
boat_load(2,0).
boat_load(0,2).
not_overpowered(0,_).
not_overpowered(M,C) :- M >= C.
/*
* List processing utilities
*/
fast_reverse(X,Y) :- fast_reverse_aux(X,Y,[]).
fast_reverse_aux([],X,X).
fast_reverse_aux([H|T],Result,Temp) :-
fast_reverse_aux(T,Result,[H|Temp]).
member(X,[X|_]).
member(X,[_|Y]) :- member(X,Y).
/*
* Routines to display the solution as a picture
*/
show_ferry([]).
show_ferry([[ML,CL,B,MR,CR]|Rest]) :-
nl, nl,
write_times('M ',ML),
write_times('C ',CL),
boat(B,Picture),
write(Picture),
write_times('M ',MR),
write_times('C ',CR),
show_ferry(Rest).
write_times(_,0).
write_times(X,N) :- /* write X, N times */
write(X),
M is N - 1,
write_times(X,M).
boat(l,'\(___) / ').
boat(r,'\ (___)/ ').